#include "mysql-connect-queue.h"

Node *createNode(MysqlConnect *connect, Node *next);            // 创建节点

void destroyNode(Node *node);                                   // 销毁节点

struct Node {
    MysqlConnect *connect;

    Node *next;

    long alive_time;
};

struct MysqlConnectQueue {
    int size;

    int capacity;

    Node *header;

    Node *tail;
};

MysqlConnectQueue *createConnectQueue(int capacity) {
    MysqlConnectQueue *queue = malloc(sizeof(MysqlConnectQueue));

    queue->size = 0;

    queue->capacity = capacity;

    queue->header = NULL;

    queue->tail = NULL;

#ifdef DEBUG_MYSQL_CONNECT_QUEUE
    printf("Create Mysql Connect Queue Success!\n");
#endif
    return queue;
}

void destroyConnectQueue(MysqlConnectQueue *queue) {
    // 关闭队列中的 MYSQL 连接
    Node *node = queue->header;
    while (node != NULL) {
        destroyConnect(node->connect);
        node = node->next;
    }

    // 清空队列的全部节点
    clear(queue);

    free(queue);
    queue = NULL;

#ifdef DEBUG_MYSQL_CONNECT_QUEUE
    printf("Destroy Mysql Connect Queue Success!\n");
#endif
}

int size(MysqlConnectQueue *queue) {
    return queue->size;
}

int capacity(MysqlConnectQueue *queue) {
    return queue->capacity;
}

bool empty(MysqlConnectQueue *queue) {
    return queue->header == NULL;
}

MysqlConnect *front(MysqlConnectQueue *queue) {
    if (queue->header != NULL) {
        return queue->header->connect;
    }

#ifdef DEBUG_PROGRAM
    printf("Mysql Connect Queue Front Is Empty!\n");
#endif
    return NULL;
}

MysqlConnect *back(MysqlConnectQueue *queue) {
    if (queue->tail != NULL) {
        return queue->tail->connect;
    }

#ifdef DEBUG_PROGRAM
    printf("Mysql Connect Queue Back Is Empty!\n");
#endif
    return NULL;
}

void clear(MysqlConnectQueue *queue) {
    Node *node = NULL;

    node = queue->header;
    while (node != NULL) {
        Node *p = node;
        node = node->next;

        destroyNode(p);
        p = NULL;
    }

    queue->size = 0;
    queue->header = NULL;
    queue->tail = NULL;

#ifdef DEBUG_MYSQL_CONNECT_QUEUE
    printf("Clear Mysql Connect Queue Success\n");
#endif
}

bool push(MysqlConnectQueue *queue, MysqlConnect *connect) {
    if (queue->size < queue->capacity) {
        Node *node = createNode(connect, NULL);
        queue->size++;

        if (queue->header == NULL) {
            queue->header = node;
            queue->tail = node;

        } else {
            queue->tail->next = node;
            queue->tail = node;
        }

        return true;
    }

#ifdef DEBUG_PROGRAM
    printf("Mysql Connect Queue Is Fill, Push Fail!\n");
#endif
    return false;
}

bool pop(MysqlConnectQueue *queue) {
    if (queue->header != NULL) {
        Node *p = queue->header;

        queue->size--;
        queue->header = queue->header->next;

        // 销毁当前节点
        destroyNode(p);

        return true;
    }

#ifdef DEBUG_PROGRAM
    printf("Mysql Connect Queue Is Empty, Pop Fail!\n");
#endif
    return false;
}

long getHeaderAliveTime(MysqlConnectQueue *queue) {
    return queue->header->alive_time;
}

Node *createNode(MysqlConnect *connect, Node *next) {
    Node *node = malloc(sizeof(Node));

    node->connect = connect;
    node->next = next;
    node->alive_time = time(NULL);

#ifdef DEBUG_PROGRAM
    printf("Create Node Success!\n");
#endif
    return node;
}

// 销毁节点时不处理节点附带的 MYSQL 连接(让连接池处理 MYSQL 连接)
void destroyNode(Node *node) {
    node->connect = NULL;
    node->next = NULL;

    free(node);
    node = NULL;

#ifdef DEBUG_PROGRAM
    printf("Destroy Node Success!\n");
#endif
}